﻿namespace Renci.iRods.Studio.Modules.Explorer.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Renci.iRods.Studio.Common.BaseClasses;
    using Renci.iRods.Data;
    using Renci.iRods.Studio.Modules.Explorer.Controls;
    using System.ComponentModel;
    using System.Windows.Input;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.Events;
    using Microsoft.Practices.ServiceLocation;
    using Renci.iRods.Studio.Modules.Explorer.Events;
    using Renci.iRods.Studio.Common;
    using Microsoft.Practices.Prism.Regions;

    public abstract class ExplorerItemModel : MetadataItemModel, IHierarchyDataItem
    {
        private SelectedObjectChangedEvent _selectedObjectChangedEvent;

        public static IEnumerable<ExplorerItemModel> GetRoot(IRodsConnection connection)
        {
            return GetChildren(connection, "/").ToList();
        }

        [DisplayName("ID"), ReadOnly(true), Browsable(true)]
        public long ID { get; protected set; }

        [DisplayName("Type Name"), ReadOnly(true), Browsable(true)]
        public abstract string TypeName { get; }

        [DisplayName("Name"), ReadOnly(true), Browsable(true)]
        public string Name { get; protected set; }

        public string FullName { get; protected set; }

        [DisplayName("Owner Name"), ReadOnly(true), Browsable(true)]
        public string OwnerName { get; protected set; }

        [DisplayName("Owner Zone"), ReadOnly(true), Browsable(true)]
        public string OwnerZone { get; protected set; }

        [DisplayName("Creation Time"), ReadOnly(true), Browsable(true)]
        public DateTime CreationTime { get; protected set; }

        [DisplayName("Modified Time"), ReadOnly(true), Browsable(true)]
        public DateTime LastWriteTime { get; protected set; }

        private IEnumerable<MenuItem> _contextCommands;
        [Browsable(false)]
        public IEnumerable<MenuItem> ContextCommands
        {
            get
            {
                if (this._contextCommands == null)
                {
                    List<MenuItem> commands = new List<MenuItem>();

                    //  Get additional commands specific to the item
                    var itemCommands = this.GetContextCommands();

                    if (itemCommands != null)
                        commands.AddRange(itemCommands);

                    //  Add common commands
                    commands.Add(new MenuItem("Metadata", new RelayCommand(() => { this.ShowMetadata(); }, () => { return true; })));
                    commands.Add(new MenuItem("Properties", new RelayCommand(() => { this.ShowProperties(); }, () => { return true; })));
                    this._contextCommands = commands;
                }

                return this._contextCommands;
            }
        }

        protected virtual IList<MenuItem> GetContextCommands()
        {
            return null;
        }

        public ExplorerItemModel(IRodsConnection connection)
            : base(connection)
        {
            var eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
            this._selectedObjectChangedEvent = eventAggregator.GetEvent<SelectedObjectChangedEvent>();
        }

        #region IHierarchyDataItem Members

        [Browsable(false)]
        public abstract bool HasChildren { get; }

        [Browsable(false)]
        public IEnumerable<IHierarchyDataItem> Children
        {
            get
            {
                return GetChildren(this.Connection, this.FullName);
            }
        }

        public IHierarchyDataItem GetParent()
        {
            throw new NotImplementedException();
        }

        #endregion

        private static IEnumerable<ExplorerItemModel> GetChildren(IRodsConnection connection, string parentName)
        {
            var collections = from c in connection.Collections
                              where c.ParentName == parentName
                              select new CollectionModel(connection, c);

            var files = from c in connection.Files
                        where c.CollectionName == parentName
                        select new FileModel(connection, c);


            foreach (var item in collections)
            {
                yield return item;
            }

            foreach (var item in files)
            {
                yield return item;
            }
        }

        private void ShowProperties()
        {
            this._selectedObjectChangedEvent.Publish(this);

            var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();

            regionManager.RequestNavigate(RegionNames.Right, new Uri("PropertiesDockableView", UriKind.Relative));

        }

        private void ShowMetadata()
        {
            this._selectedObjectChangedEvent.Publish(this);

            var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();

            regionManager.RequestNavigate(RegionNames.Right, new Uri("MetadataDockableView", UriKind.Relative));

        }
    }
}
